import collectdata from "./collectdata.mjs";
import datarover from "./datarover.mjs";
import { after } from "./delay_render.mjs";
import { nearest_render } from "./nearest.mjs";
import render_helper from "./render_helper.mjs";
import thin_render from "./thin_render.mjs";

function tablehead(table, cols, onfilter) {
  let colgroup = document.createElement("colgroup");
  table.appendChild(colgroup);
  let thead = document.createElement("thead");
  table.appendChild(thead);
  let headerrow = document.createElement("tr");
  thead.appendChild(headerrow);

  for (let col of cols) {
    // console.log(col);
    let co = document.createElement("col");
    colgroup.appendChild(co);
    render_helper(co, { width: col.width });
    let th = document.createElement("th");
    headerrow.appendChild(th);
    if (typeof col.title !== "undefined") {
      thin_render(th, col.title);
    } else if (typeof col.col === "string") {
      thin_render(th, col.col);
    }
  }

  // 渲染过滤器
  if (
    cols?.find((col) => {
      return col.filter !== undefined;
    })
  ) {
    let filterrow = document.createElement("tr");
    thead.appendChild(filterrow);
    // after(() => {
    cols.forEach((col) => {
      let td = document.createElement("td");
      filterrow.appendChild(td);
      if (col.class) {
        td.setAttribute("class", col.class);
      }
      if (col.filter === undefined) {
      } else if (col.filter.input) {
        thin_render(td, {
          input: col.filter.input,
          value: "[[filter/" + col.filter.input + "]]",
          event: { change: col.filter.event?.change || filter_handler },
        });
      } else if (col.filter.select) {
        if (col.filter.datapath) {
          let options =
            col.filter.emptyforall === true
              ? [""].concat(datarover(td, col.filter.datapath))
              : datarover(td, col.filter.datapath);
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            options: options,
            event: { change: col.filter.event?.change || filter_handler },
          });
        } else if (col.filter.ajax) {
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            ajax: col.filter.ajax,
            event: { change: col.filter.event?.change || filter_handler },
          });
        } else {
          thin_render(td, {
            select: col.filter.select,
            value: "[[filter/" + col.filter.select + "]]",
            options: col.filter.options,
            event: { change: col.filter.event?.change || filter_handler },
          });
        }
      } else thin_render(td, col.filter);
      // });
      //filter事件
    });

    function filter_handler(ev) {
      let filter = {};
      let d = collectdata(filterrow);
      for (let key in d) {
        // console.log(key);
        if (d[key] !== "") {
          filter[key] = d[key];
        }
      }

      if (onfilter) {
        onfilter({ filter: filter });
      }
    }
  }
}

function datarows({
  container: tbody,
  cols,
  rows,
  rowdrag,
  rowclass,
  mode = "read",
  rowclick,
  rowchange,
  rowinsert,
  rowdelete,
}) {
  // 数据行
  if (Array.isArray(rows)) {
    tbody.thin_rowdata = rows;
    let rowindex = 0;
    rows.forEach((row) => {
      let tr = document.createElement("tr");
      tr.thin_data = row;
      tr.thin_rowindex = rowindex;
      tbody.appendChild(tr);

      if (rowdrag) tr.setAttribute("draggable", true);

      if (rowclass) {
        if (typeof rowclass === "function") {
          tr.classList.add(rowclass(row));
        } else {
          tr.classList.add(rowclass);
        }
      }

      row_render({ tr, row, cols, mode, rowclick });

      rowindex++;
    });
  }

  function row_render({ tr, row, cols, insert, mode, rowclick }) {
    cols.forEach((col) => {
      let td = document.createElement("td");
      tr.appendChild(td);

      render_helper(td, { click: col.click });
      // class
      if (typeof col.class === "function") {
        let _class = col.class(row);
        _class?.split(" ").forEach((c) => {
          td.classList.add(c);
        });
      } else if (col.class) {
        col.class?.split(" ").forEach((c) => {
          td.classList.add(c);
        });
      }

      if (mode === "edit") {
        if (/\[\[[\w/.]+\]\]/.test(col.col)) normal_col();
        else if (col.readonly && !insert) normal_col();
        else edit_col();
      } else normal_col();

      function normal_col() {
        if (/\[\[[\w/.]+\]\]/.test(col.col)) {
          thin_render(td, col.col);
        } else if (col.NumberFormat) {
          let d = datarover(td, col.col);
          console.log(d);
          if (d === undefined) {
          } else if (Number.isNaN(d)) {
            td.innerText = d;
          } else {
            td.innerText = new Intl.NumberFormat(
              "en-US",
              col.NumberFormat
            ).format(d);
          }
          bindrowclick();
        } else if (col.DateTimeFormat) {
          let d = datarover(td, col.col);
          d = d?.replace(/\//g, "-");
          let t = new Date(`${d}`);
          // let t = Date.parse(d);
          // console.log({ d, t });
          if (d === undefined) {
          } else if (!isNaN(t.getTime())) {
            t = Date.UTC(
              t.getFullYear(),
              t.getMonth(),
              t.getDate(),
              t.getHours(),
              t.getMinutes(),
              t.getSeconds(),
              t.getMilliseconds()
            );
            td.innerText = new Intl.DateTimeFormat(
              "default",
              col.DateTimeFormat
            ).format(t);
          }
          bindrowclick();
        } else if (typeof col.col === "string") {
          if (col.ajax?.display) {
            let q = {};
            q[col.ajax.value] = datarover(td, col.col);
            // console.log(q);
            thin_ajax({
              type: "get",
              url: col.ajax.url,
              data: { ...col.ajax.query, ...q },
              success: (data) => {
                // console.log(data);
                let d = datarover(data, col.ajax.datapath);
                // console.log({ d });
                if (d === undefined) {
                  thin_render(td, col.col);
                } else if (Array.isArray(d) && d.length === 1) {
                  thin_render(td, render_content(d[0], col.ajax.display));
                } else {
                  thin_render(td, `[[${col.col}]]`);
                }
              },
            });
          } else if (col.col) {
            thin_render(td, `[[${col.col}]]`);
          }
          bindrowclick();
        } else if (
          typeof col.col === "object" ||
          typeof col.col === "function"
        ) {
          thin_render(td, col.col);
        } else {
          console.log({ col });
        }

        function bindrowclick() {
          if (rowclick)
            render_helper(td, {
              click: (e) => {
                savescrollpos(tbody);
                rowclick(e);
              },
            });
        }
      }

      function edit_col() {
        if (typeof col.col === "object") {
          thin_render(td, col.col);
        } else if (col.type === "checkbox" || col.type === "select") {
          thin_render(td, {
            input: col.col,
            type: col.type,
            bind: col.col,
            options: col.options,
            ajax: col.ajax,
            a: col.a,
            event: {
              change: (e) => {
                if (template.rowchange && !insert) template.rowchange(e);
              },
            },
          });
        } else if (insert) {
          switch (col.type) {
            default:
              let t = {
                input: col.col,
                type: col.type,
                ajax: col.ajax,
                options: col.options,
                a: col.a,
                event: {
                  change: (e) => {
                    if (template.rowchange && !insert) template.rowchange(e);
                  },
                },
              };
              if (col.col) t.bind = col.col;
              thin_render(td, t);
              break;
          }
        } else {
          let underline = document.createElement("underline");
          td.appendChild(underline);
          render_value();

          function render_value() {
            switch (typeof col.col) {
              case "string":
                let value = datarover(td, col.col);
                if (value === undefined) {
                } else if (col.NumberFormat) {
                  underline.innerText = new Intl.NumberFormat(
                    "en-US",
                    col.NumberFormat
                  ).format(value);
                } else if (col.DateTimeFormat) {
                  value = value?.replace(/\//g, "-");
                  value = new Date(`${value}`);
                  underline.innerText = !isNaN(value.getTime())
                    ? new Intl.DateTimeFormat(
                        "default",
                        col.DateTimeFormat
                      ).format(
                        Date.UTC(
                          value.getFullYear(),
                          value.getMonth(),
                          value.getDate(),
                          value.getHours(),
                          value.getMinutes(),
                          value.getSeconds(),
                          value.getMilliseconds()
                        )
                      )
                    : "";
                } else underline.innerText = value;
                break;
            }
          }

          underline.onclick = (e) => {
            console.log(e);
            if (typeof col.edit === "function") {
              col.edit({
                element: td,
                data: nearest_data(td),
                done: function () {
                  render_value();
                },
                changed: function (result) {
                  Object.assign(nearest_data(td), result);
                  if (template.rowchange)
                    template.rowchange({
                      new_data: {},
                      org_data: nearest_data(td),
                    });
                  render_value();
                },
              });
            } else {
              let t;
              if (typeof col.edit === "object") {
                t = col.edit;
              } else {
                switch (col.type) {
                  default:
                    t = [
                      { div: `${col.col}:` },
                      {
                        input: col.col,
                        value: `[[${col.col}]]`,
                        type: col.type,
                        ajax: col.ajax,
                        a: col.a,
                      },
                      "<br/>",
                      "<br/>",
                    ];
                }
              }
              confirm(t, nearest_data(td)).confirmed((result) => {
                console.log(result);
                Object.assign(nearest_data(td), result);
                if (rowchange)
                  rowchange({
                    new_data: {},
                    org_data: nearest_data(td),
                  });
                render_value();
              });
            }
          };
        }
      }
    });

    if ((rowinsert || rowdelete) && mode === "edit") {
      let td = document.createElement("td");
      tr.appendChild(td);
      if (!insert && rowdelete) {
        thin_render(td, {
          button: "delete",
          click: (e) => {
            console.log({ delete: e, template });
            if (typeof rowdelete === "function") {
              rowdelete(e);
            } else if (rowdelete === true) {
              console.log(e);
              // let d = nearest_data(tbody);
              let d = tbody.thin_rowdata;
              d.splice(e.rowindex, 1);
              thin(tbody).empty();
              row_group(tbody, d);
            }
          },
        });
      }
      if (insert) {
        thin_render(td, {
          button: "insert",
          click: (e) => {
            if (typeof rowinsert === "function") {
              validate({
                container: tr,
                valid: () => {
                  rowinsert(e);
                },
                invalid: () => {
                  e.done();
                },
              });
            } else if (rowinsert === true) {
              // let d = nearest_data(tbody);
              let d = tbody.thin_rowdata;
              validate({
                container: tr,
                valid: function () {
                  // console.log({ e, d });
                  d.push({ ...e.new_data, ...e.org_data });
                  thin(tbody).empty();
                  row_group(tbody, d);
                },
                invalid: function () {
                  e.done();
                },
              });
            }
          },
        });
      }
    }
  }
}

function savescrollpos(container) {
  let rerender_container = nearest_render(container.parent);
  console.log({ rerender_container });
  // if (template.id) {
  //   rerender_container[`thin_gridview_${template.id}`] = {
  //     top: gridview.scrollTop,
  //     left: gridview.scrollLeft,
  //   };
  // }
  // console.log({ rerender_container });
}

function restorescrollpos() {
  if (template.id) {
    let rerender_container = nearest_render(gridview);
    let pos = rerender_container[`thin_gridview_${template.id}`];
    // console.log({ pos });
    if (pos) {
      gridview.scrollTo(pos);
    }
  }
}

export { tablehead, datarows };
